package com.upstairstechnology.oi.determination.perforce;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.upstairstechnology.oi.determination.CommandReaderErrorHandler;

/**
 * Perforce command reader error handler.
 * 
 * @author Jeff Jensen
 */
public class CommandReaderErrorHandlerPerforce implements
        CommandReaderErrorHandler {
    /** Logger instance. */
    private static final Logger LOGGER =
            LoggerFactory.getLogger(CommandReaderErrorHandlerPerforce.class);

    /**
     * {@inheritDoc}
     */
    public void handle(List<String> command) {
        logP4Env();
    }

    /**
     * Log the Perforce environment information to the logger.
     */
    protected void logP4Env() {
        List<String> cmd = new ArrayList<String>();
        cmd.add("p4");
        cmd.add("set");

        final String headMsg = "'p4 set' output:";
        final String errMsg =
                "Attempted to log Perforce environment information,"
                        + " but caught Exception:";
        logInfo(cmd, headMsg, errMsg);
    }

    /**
     * Log info for debugging/error help purposes.
     * 
     * @param cmd
     *            Program called and its arguments.
     * @param headMsg
     *            First message logged, before the stdin messages.
     * @param errMsg
     *            Message logged if an IOException encountered.
     * @TODO where to move this to for generic use? create abstract base class?
     */
    protected void logInfo(List<String> cmd, String headMsg, String errMsg) {
        Process process = null; // NOPMD
        try {
            ProcessBuilder processBuilder = new ProcessBuilder(cmd);
            process = processBuilder.start();

            BufferedReader inStd = setupIn(process.getInputStream());
            BufferedReader inErr = setupIn(process.getErrorStream());

            String lineStd = null; // NOPMD

            LOGGER.error(headMsg);
            while (null != (lineStd = inStd.readLine())) { // NOPMD
                LOGGER.debug("    {}", lineStd);
            }

            inStd.close();
            inErr.close();
        } catch (IOException e) {
            LOGGER.error(errMsg, e);
        } finally {
            if (process != null) {
                process.destroy();
            }
        }
    }

    /**
     * Setup the input stream as needed for use.
     * 
     * @param is
     *            InputStream to wrap in a BufferedReader.
     * @return BufferedReader to use.
     * @TODO how to not duplicate this?
     */
    public BufferedReader setupIn(InputStream is) {
        InputStreamReader isr = new InputStreamReader(is);
        BufferedReader br = new BufferedReader(isr);
        return br;
    }
}
